﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using BL;
using BL.Model.Request;
using Common;
using DAL.Model;

namespace UI.MainFunctions
{
    public partial class frmStockInManager : Base.DialogViewBase
    {
        #region Variables

        private readonly MasterSession _session;
        private readonly StockInController _stockInController;

        #endregion

        #region Constructor

        public frmStockInManager ()
        {
            InitializeComponent();
            _session = new MasterSession();
            _stockInController = new StockInController(_session);
        }

        #endregion
        
        #region Override Methods

        protected override void PopulateStaticData ()
        {
            base.PopulateStaticData();
            deFromDate.DateTime = DateTime.Now.AddDays(-7);
            deToDate.DateTime = DateTime.Now;

            LoadUoms();
            LoadPackageTypes();
            LoadCustomers();
            LoadProductCats();
        }

        protected override void PopulateData ()
        {
            base.PopulateData();

            DateTime fromDate = deFromDate.DateTime > Constant.MinDate
                                    ? deFromDate.DateTime.Date
                                    : Constant.MinDate;
            DateTime toDate = deToDate.DateTime < Constant.MaxDate
                                  ? deToDate.DateTime.Date.AddDays(1)
                                  : Constant.MaxDate;

            var request = new SearchingStockInRequest
            {
                FromTime = fromDate,
                ToTime = toDate,
                IsPaging = false,
                DocumentNo = txtDocumentNo.Text,
                ProductCode = txtProductCode.Text
            };

            int customerId;
            if (lueCustomers.EditValue != null && int.TryParse(lueCustomers.EditValue.ToString(), out customerId))
            {
                request.CustomerIds = new List<int> { customerId };
            }
            else
            {
                request.CustomerIds = new List<int> { Constant.AllValue };
            }
            int merchantId;
            if (lueMerchant.EditValue != null && int.TryParse(lueMerchant.EditValue.ToString(), out merchantId))
            {
                request.MerchantIds = new List<int> { merchantId };
            }
            else
            {
                request.MerchantIds = new List<int> { Constant.AllValue };
            }
            int productCategoryId;
            if (lueProductCat.EditValue != null && int.TryParse(lueProductCat.EditValue.ToString(), out productCategoryId))
            {
                request.ProductCategoryIds = new List<int> { productCategoryId };
            }
            else
            {
                request.ProductCategoryIds = new List<int> { Constant.AllValue };
            }

            var stockIns = _stockInController.Search(request);
            dgStockIns.DataSource = null;
            dgStockIns.DataSource = stockIns;
            gvStockIns.BestFitColumns();

            var rowCount = stockIns.Count;
            for (int i = 0; i < rowCount; i++)
            {
                gvStockIns.ExpandMasterRow(i);
            }
        }

        protected override void FormatPrecision()
        {
            PrecisionHelper.FormatCurencyPrecision(gcTotalQuantity,
                                                   gcNetQuantity,
                                                   gcGrossQuantity,
                                                   gcQty,
                                                   gcPackageQuantity,
                                                   gcStockOutMassQty,
                                                   gcStockoutQty);
        }

        #endregion

        #region Private Methods
        
        private void LoadUoms()
        {
            var uoms = _session.UnitOfMeasures.ToArray();
            lueUom.DataSource = uoms;
            luePackageTypeUom.DataSource = uoms;
        }

        private void LoadProductCats()
        {
            var productCats = _session.ProductCategories.ToList();
            productCats.Insert(0, new ProductCategory { Id = -1, Name = string.Empty });
            lueProductCat.Properties.DataSource = productCats;
        }

        private void LoadCustomers()
        {
            var customers = _session.Customers.OrderBy(t=>t.Name).ToList();
            customers.Insert(0, new Customer {Id = -1, Name = string.Empty});
            lueCustomers.Properties.DataSource = customers;
            lueMerchant.Properties.DataSource = customers;
        }

        private void LoadPackageTypes()
        {
            var packageTypes = _session.PackageTypes.ToArray();
            luePackageType.DataSource = packageTypes;
        }
        
        #endregion
        
        private void gvStockIns_MasterRowGetChildList(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetChildListEventArgs e)
        {
            var row = (StockIn)gvStockIns.GetRow(e.RowHandle);
            e.ChildList = new BindingSource(row, "StockInDetails");
        }

        private void gvStockIns_MasterRowGetRelationCount(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetRelationCountEventArgs e)
        {
            e.RelationCount = 1;
        }

        private void gvStockIns_MasterRowEmpty(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowEmptyEventArgs e)
        {
            var row = (StockIn)gvStockIns.GetRow(e.RowHandle);
            e.IsEmpty = row.StockInDetails.Count == 0;
        }
        
        private void gvStockIns_MasterRowGetRelationName(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetRelationNameEventArgs e)
        {
            e.RelationName = "StockInDetails";
        }

        private void spFind_Click(object sender, EventArgs e)
        {
            PopulateData();
        }

        private void spView_Click(object sender, EventArgs e)
        {
            if(gvStockIns.FocusedRowHandle <= -1)
            {
                return;
            }
            var stockIn = (StockIn) gvStockIns.GetRow(gvStockIns.FocusedRowHandle);
            if(stockIn == null)
            {
                return;
            }
            var frmStockIn = new frmStockIn(stockIn.Id, FormAction.View)
                                 {
                                     MdiParent = MdiParent
                                 };
            frmStockIn.Show();
        }

        private void spAdd_Click(object sender, EventArgs e)
        {
            var frmStockIn = new frmStockIn(FormAction.New)
                                 {
                                     MdiParent = MdiParent
                                 };
            frmStockIn.Show();
        }

        private void spEdit_Click(object sender, EventArgs e)
        {
            if(gvStockIns.FocusedRowHandle <= -1)
            {
                return;
            }
            var stockIn = (StockIn) gvStockIns.GetRow(gvStockIns.FocusedRowHandle);
            if(stockIn == null)
            {
                return;
            }
            var frmStockIn = new frmStockIn(stockIn.Id, FormAction.Edit)
                                 {
                                     MdiParent = MdiParent
                                 };
            frmStockIn.Show();
        }

        private void spGenerateTranfer_Click(object sender, EventArgs e)
        {
            var selectedRows = gvStockIns.GetSelectedRows();
            var customers = selectedRows
                .Select(rowHandle => gvStockIns.GetRow(rowHandle))
                .OfType<StockIn>()
                .Select(t => t.CustomerId)
                .ToArray();
            if (customers.Count() > 2)
            {
                MessageBox.Show("Không thể gia công cho nhiều khách hàng cùng lúc",
                                "Thông báo",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return;
            }
            var stockInIds = selectedRows
                .Select(rowHandle => gvStockIns.GetRow(rowHandle))
                .OfType<StockIn>()
                .Where(t => t.StockInDetails.All(detail => detail.Quantity > detail.StockOutMassQuantity))
                .Select(selectedStockIn => selectedStockIn.Id)
                .ToList();

            if (stockInIds.Count == 0)
            {
                MessageBox.Show("Đã xuất kho hết hàng. Không thể tiếp tục xuất gia công",
                                "Thông báo",
                                MessageBoxButtons.OK);
                return;
            }

            var newSession = new MasterSession();
            var transferController = new TransferController(newSession);
            var transfer = transferController.GenTranferFromStockIns(stockInIds);

            if (transfer == null)
            {

                MessageBox.Show("Phiếu nhập đã gia công hết số lượng", "Thông báo",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return;
            }

            var frmTransfer = new frmTransfer(transfer,
                                              FormAction.New,
                                              newSession)
                                  {
                                      MdiParent = MdiParent
                                  };
            frmTransfer.Show();
        }

        private void spReturnGoods_Click(object sender, EventArgs e)
        {
            var selectedRows = gvStockIns.GetSelectedRows();
            var customers = selectedRows
                .Select(rowHandle => gvStockIns.GetRow(rowHandle))
                .OfType<Transfer>()
                .Select(t => t.CustomerId)
                .ToArray();
            if (customers.Count() > 2)
            {
                MessageBox.Show("Không thể xuất kho cho nhiều khách hàng cùng lúc",
                                "Thông báo",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return;
            }
            var stockInIds = selectedRows
                .Select(rowHandle => gvStockIns.GetRow(rowHandle))
                .OfType<StockIn>()
                .Select(t=>t.Id)
                .ToArray();

            var stoSession = new MasterSession();
            var stockOutController = new StockOutController(stoSession);
            var stockOut = stockOutController.GenStockOutFromStockIns(stockInIds);

            if (stockOut == null)
            {
                MessageBox.Show("Hàng nhập đã xuất hết số lượng.");
                return;
            }
            var frmStockOut = new frmStockOut(stockOut,
                                              FormAction.New, stoSession)
                                  {
                                      MdiParent = MdiParent
                                  };
            frmStockOut.Show();
        }
    }
}
